package com.example.vault.controller;

import com.example.vault.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * Redis集群管理控制器
 * 提供Redis连接测试、缓存管理、会话管理和分布式锁功能的API
 */
@RestController
@RequestMapping("/api/redis")
public class RedisController {

    @Autowired
    private RedisService redisService;

    /**
     * Redis集群健康检查
     */
    @GetMapping("/health")
    public Map<String, Object> healthCheck() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> clusterInfo = redisService.getRedisClusterInfo();
            result.put("status", "success");
            result.put("message", "Redis集群连接正常");
            result.put("cluster_info", clusterInfo);
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "Redis集群连接失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取Redis使用统计
     */
    @GetMapping("/stats")
    public Map<String, Object> getStats() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> stats = redisService.getRedisUsageStats();
            result.put("status", "success");
            result.put("message", "Redis统计信息获取成功");
            result.put("stats", stats);
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "获取Redis统计信息失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 测试Redis缓存功能
     */
    @PostMapping("/cache/test")
    public Map<String, Object> testCache(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String testKey = "test_" + System.currentTimeMillis();
            String testValue = request.getOrDefault("value", "test_value").toString();
            int timeout = Integer.parseInt(request.getOrDefault("timeout", "60").toString());
            
            // 设置缓存
            redisService.setCache(testKey, testValue, timeout, TimeUnit.SECONDS);
            
            // 读取缓存
            Object cachedValue = redisService.getCache(testKey);
            
            // 检查缓存是否存在
            Boolean exists = redisService.hasCache(testKey);
            
            // 获取过期时间
            Long expireTime = redisService.getCacheExpire(testKey);
            
            result.put("status", "success");
            result.put("message", "缓存测试成功");
            result.put("test_key", testKey);
            result.put("original_value", testValue);
            result.put("cached_value", cachedValue);
            result.put("exists", exists);
            result.put("expire_time", expireTime);
            result.put("match", testValue.equals(cachedValue));
            
            // 清理测试数据
            redisService.deleteCache(testKey);
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "缓存测试失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 测试用户会话管理
     */
    @PostMapping("/session/test")
    public Map<String, Object> testSession(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String userId = request.getOrDefault("user_id", "test_user_" + System.currentTimeMillis()).toString();
            int timeout = Integer.parseInt(request.getOrDefault("timeout", "1800").toString()); // 30分钟
            
            // 创建会话数据
            Map<String, Object> sessionData = new HashMap<>();
            sessionData.put("user_id", userId);
            sessionData.put("username", "测试用户");
            sessionData.put("login_time", System.currentTimeMillis());
            sessionData.put("ip_address", "127.0.0.1");
            
            // 设置用户会话
            redisService.setUserSession(userId, sessionData, timeout, TimeUnit.SECONDS);
            
            // 读取用户会话
            Map<String, Object> retrievedSession = redisService.getUserSession(userId);
            
            // 检查用户是否在线
            Boolean isOnline = redisService.isUserOnline(userId);
            
            // 刷新会话
            Boolean refreshed = redisService.refreshUserSession(userId, timeout, TimeUnit.SECONDS);
            
            result.put("status", "success");
            result.put("message", "会话测试成功");
            result.put("user_id", userId);
            result.put("session_data", sessionData);
            result.put("retrieved_session", retrievedSession);
            result.put("is_online", isOnline);
            result.put("refreshed", refreshed);
            
            // 清理测试数据
            redisService.deleteUserSession(userId);
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "会话测试失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 测试分布式锁功能
     */
    @PostMapping("/lock/test")
    public Map<String, Object> testDistributedLock(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String lockKey = request.getOrDefault("lock_key", "test_lock_" + System.currentTimeMillis()).toString();
            String lockValue = UUID.randomUUID().toString();
            int timeout = Integer.parseInt(request.getOrDefault("timeout", "300").toString()); // 5分钟
            
            // 尝试获取锁
            Boolean lockAcquired = redisService.tryLock(lockKey, lockValue, timeout, TimeUnit.SECONDS);
            
            if (lockAcquired) {
                // 检查锁是否存在
                Boolean lockExists = redisService.isLocked(lockKey);
                
                // 获取锁的值
                String currentLockValue = redisService.getLockValue(lockKey);
                
                // 尝试再次获取同一个锁（应该失败）
                Boolean secondLockAttempt = redisService.tryLock(lockKey, UUID.randomUUID().toString(), 1, TimeUnit.SECONDS);
                
                // 释放锁
                Boolean lockReleased = redisService.releaseLock(lockKey, lockValue);
                
                // 检查锁是否已释放
                Boolean lockExistsAfterRelease = redisService.isLocked(lockKey);
                
                result.put("status", "success");
                result.put("message", "分布式锁测试成功");
                result.put("lock_key", lockKey);
                result.put("lock_value", lockValue);
                result.put("lock_acquired", lockAcquired);
                result.put("lock_exists", lockExists);
                result.put("current_lock_value", currentLockValue);
                result.put("second_lock_attempt", secondLockAttempt);
                result.put("lock_released", lockReleased);
                result.put("lock_exists_after_release", lockExistsAfterRelease);
                
            } else {
                result.put("status", "warning");
                result.put("message", "无法获取分布式锁，可能已被其他进程占用");
                result.put("lock_key", lockKey);
                result.put("lock_acquired", false);
            }
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "分布式锁测试失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 支付订单缓存测试
     */
    @PostMapping("/payment/cache/test")
    public Map<String, Object> testPaymentCache(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String orderId = request.getOrDefault("order_id", "ORDER_" + System.currentTimeMillis()).toString();
            
            // 创建订单信息
            Map<String, Object> orderInfo = new HashMap<>();
            orderInfo.put("order_id", orderId);
            orderInfo.put("user_id", "USER001");
            orderInfo.put("amount", 100.00);
            orderInfo.put("status", "PENDING");
            orderInfo.put("create_time", System.currentTimeMillis());
            
            // 缓存支付订单
            redisService.cachePaymentOrder(orderId, orderInfo);
            
            // 读取缓存的订单
            Map<String, Object> cachedOrder = redisService.getCachedPaymentOrder(orderId);
            
            result.put("status", "success");
            result.put("message", "支付订单缓存测试成功");
            result.put("original_order", orderInfo);
            result.put("cached_order", cachedOrder);
            result.put("cache_match", orderInfo.equals(cachedOrder));
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "支付订单缓存测试失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 支付分布式锁测试
     */
    @PostMapping("/payment/lock/test")
    public Map<String, Object> testPaymentLock(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String orderId = request.getOrDefault("order_id", "ORDER_" + System.currentTimeMillis()).toString();
            String userId = request.getOrDefault("user_id", "USER_" + System.currentTimeMillis()).toString();
            String lockValue = UUID.randomUUID().toString();
            
            // 测试支付订单锁
            Boolean orderLockAcquired = redisService.lockPaymentOrder(orderId, lockValue);
            Boolean orderLockReleased = false;
            if (orderLockAcquired) {
                orderLockReleased = redisService.unlockPaymentOrder(orderId, lockValue);
            }
            
            // 测试用户支付锁
            String userLockValue = UUID.randomUUID().toString();
            Boolean userLockAcquired = redisService.lockUserPayment(userId, userLockValue);
            Boolean userLockReleased = false;
            if (userLockAcquired) {
                userLockReleased = redisService.unlockUserPayment(userId, userLockValue);
            }
            
            result.put("status", "success");
            result.put("message", "支付分布式锁测试成功");
            result.put("order_id", orderId);
            result.put("user_id", userId);
            result.put("order_lock_acquired", orderLockAcquired);
            result.put("order_lock_released", orderLockReleased);
            result.put("user_lock_acquired", userLockAcquired);
            result.put("user_lock_released", userLockReleased);
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "支付分布式锁测试失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 清理过期数据
     */
    @PostMapping("/cleanup")
    public Map<String, Object> cleanupExpiredData() {
        try {
            return redisService.cleanupExpiredData();
        } catch (Exception e) {
            Map<String, Object> result = new HashMap<>();
            result.put("status", "error");
            result.put("message", "清理过期数据失败: " + e.getMessage());
            return result;
        }
    }

    /**
     * 获取Redis集群详细信息
     */
    @GetMapping("/cluster/info")
    public Map<String, Object> getClusterInfo() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> clusterInfo = redisService.getRedisClusterInfo();
            Map<String, Object> usageStats = redisService.getRedisUsageStats();
            
            result.put("status", "success");
            result.put("message", "Redis集群信息获取成功");
            result.put("cluster_info", clusterInfo);
            result.put("usage_stats", usageStats);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "获取Redis集群信息失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 综合功能测试
     */
    @PostMapping("/test/all")
    public Map<String, Object> testAllFeatures() {
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> testResults = new HashMap<>();
        
        try {
            // 测试缓存
            Map<String, Object> cacheTest = testCache(Map.of("value", "test_cache", "timeout", "60"));
            testResults.put("cache_test", cacheTest);
            
            // 测试会话
            Map<String, Object> sessionTest = testSession(Map.of("user_id", "test_user", "timeout", "1800"));
            testResults.put("session_test", sessionTest);
            
            // 测试分布式锁
            Map<String, Object> lockTest = testDistributedLock(Map.of("lock_key", "test_lock", "timeout", "300"));
            testResults.put("lock_test", lockTest);
            
            // 测试支付缓存
            Map<String, Object> paymentCacheTest = testPaymentCache(Map.of("order_id", "TEST_ORDER"));
            testResults.put("payment_cache_test", paymentCacheTest);
            
            // 测试支付锁
            Map<String, Object> paymentLockTest = testPaymentLock(Map.of("order_id", "TEST_ORDER", "user_id", "TEST_USER"));
            testResults.put("payment_lock_test", paymentLockTest);
            
            result.put("status", "success");
            result.put("message", "Redis综合功能测试完成");
            result.put("test_results", testResults);
            result.put("timestamp", System.currentTimeMillis());
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "Redis综合功能测试失败: " + e.getMessage());
            result.put("test_results", testResults);
        }
        
        return result;
    }
}